package ace.cmp.core.utils;

import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author caspar
 * @date 2023/9/15 9:12
 */
public class SystemClockUtils {

  private final long period;

  private final AtomicLong now;

  private SystemClockUtils(long period) {
    this.period = period;
    this.now = new AtomicLong(System.currentTimeMillis());
    scheduleClockUpdating();
  }

  private static SystemClockUtils instance() {
    return InstanceHolder.INSTANCE;
  }

  public static long currentTimeMillis() {
    return instance().now.get();
  }

  private void scheduleClockUpdating() {
    ScheduledThreadPoolExecutor scheduler =
        new ScheduledThreadPoolExecutor(
            1,
            r -> {
              Thread thread = new Thread(r, "system-clock-utils");
              thread.setDaemon(true);
              return thread;
            });

    scheduler.scheduleAtFixedRate(
        () -> now.set(System.currentTimeMillis()), period, period, TimeUnit.MILLISECONDS);
  }

  private static class InstanceHolder {
    public static final SystemClockUtils INSTANCE = new SystemClockUtils(1);
  }
}
